﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;

public enum Atributo
{
    NONE,
    CARISMA,
    INTELIGENCIA,
    PERCEPCAO
}

public class Objects
{
    private Vector2 posicao;
    private Texture2D imagem;
    //private String pista;
    private bool interactionPossible;
    private bool interactionImpossible;
    private bool clicked;
    private SpriteFont font;
    private bool wasClicked;
    private List<Mensagem> mensagens;
    private string pista;
    private List<Condition> need, give;

    public List<Mensagem> Messages
    {
        get { return mensagens; }
        set { mensagens = value; }
    }

    public List<Condition> Condition
    {
        get { return need; }
        set { need = value; }
    }

    public List<Condition> Give
    {
        get { return give; }
        set { give = value; }
    }
    public bool InteractionPossible
    {
        get { return interactionPossible; }
        set
        {
            interactionPossible = value;
        }
    }

    public bool InteractionImpossible
    {
        get { return interactionImpossible; }
        set
        {
            interactionImpossible = value;
        }
    }

    public bool Clicked
    {
        get { return clicked; }
        set 
        { 
            clicked = value;
        }
    }

    public Vector2 Posicao
    {
        get { return posicao; }
        set { posicao = value; }
    }

    public SpriteFont Font
    {
        get { return font; }
        set { font = value; }
    }

    public Texture2D Imagem
    {
        get { return imagem; }
        set { imagem = value; }
    }

    public String Pista
    {
        get 
        {    
            return pista;
        }
    }

    public Objects(SpriteFont font) 
    {
        mensagens = new List<Mensagem>();
        this.font = font;
        give = new List<Condition>();
        need = new List<Condition>();
    }

    public Objects(Vector2 posicao, Texture2D imagem, SpriteFont font)
    {
        this.posicao = posicao;
        this.imagem = imagem;
        this.font = font;
    }


    private bool CheckSelected()
    {
        MouseState state = InputManager.MouseState;
        if (state.X > posicao.X && state.Y > posicao.Y && state.X < posicao.X + imagem.Width && state.Y < posicao.Y + imagem.Height)
        {
            if (CheckSelectedPixel())
            {
                if (!InteractionPossible && !InteractionImpossible)
                {
                    AudioManager.PlaySound("Audio/s02");
                    //Console.WriteLine("2");
                }
                return InteractionPossible = true;
            }
            else
            {
                return InteractionPossible = false;
            }
        }
        else
        {
            return InteractionPossible = false;
        }
    }

    private bool CheckSelectedPixel()
    {
        MouseState state = Mouse.GetState();

        Color[] tileTextureData = new Color[imagem.Width * imagem.Height];
        imagem.GetData(0, new Rectangle(0, 0, imagem.Width, imagem.Height), tileTextureData, 0, imagem.Width * imagem.Height);

        Color[] pixel = new Color[1];
        pixel[0] = Color.Black;

        return IntersectPixels(new Rectangle((int)posicao.X, (int)posicao.Y, imagem.Width, imagem.Height), tileTextureData, 
            new Rectangle(state.X, state.Y, 1, 1), pixel);

    }

    public bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB)
    {
        int top = Math.Max(rectangleA.Top, rectangleB.Top);
        int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
        int left = Math.Max(rectangleA.Left, rectangleB.Left);
        int right = Math.Min(rectangleA.Right, rectangleB.Right);

        for (int y = top; y < bottom; y++)
        {
            for (int x = left; x < right; x++)
            {
                Color colorA = dataA[(x - rectangleA.Left) +
                                     (y - rectangleA.Top) * rectangleA.Width];
                Color colorB = dataB[(x - rectangleB.Left) +
                                     (y - rectangleB.Top) * rectangleB.Width];

                if (colorA.A != 0 && colorB.A != 0)
                {
                    return true;
                }
            }
        }
        return false;
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        if (Clicked)
        {
            spriteBatch.Draw(Imagem, new Rectangle((int)Posicao.X, (int)Posicao.Y, Imagem.Width, Imagem.Height), Color.Goldenrod);
            WriteString(spriteBatch, Pista, 610);
        }
        else
            if (InteractionPossible)
                spriteBatch.Draw(Imagem, new Rectangle((int)Posicao.X, (int)Posicao.Y, Imagem.Width, Imagem.Height), Color.Gold);
            else
                if (InteractionImpossible)
                    spriteBatch.Draw(Imagem, new Rectangle((int)Posicao.X, (int)Posicao.Y, Imagem.Width, Imagem.Height), Color.Red);
                else
                    spriteBatch.Draw(Imagem, new Rectangle((int)Posicao.X, (int)Posicao.Y, Imagem.Width, Imagem.Height), Color.White);

    }

    private int WriteString(SpriteBatch spriteBatch, string text, int y)
    {
        string[] words = text.Split(' ');

        string aux = "";

        int draws = 0;

        for (int i = 0; i < words.Length; i++)
        {
            if (aux.Equals(""))
                aux += words[i];
            else
                aux += " " + words[i];

            //if (aux.Length > 140)
            if (font.MeasureString(aux).X > 800)
            {
                spriteBatch.DrawString(font, aux, new Vector2(250, y + draws * 25), Color.Black);
                draws++;
                aux = "";
            }
        }
        spriteBatch.DrawString(font, aux, new Vector2(250, y + draws * 25), Color.Black);
        draws++;

        return draws;
    }

    /*public void Update(List<Objects> objectList, ref int interactionCount)
    {
        if (Globals.FirstItem)
            return;

        CheckSelected();

        InteractionImpossible = false;

        if (InteractionPossible && !(interactionCount > 0 || wasClicked))
        {
            InteractionPossible = false;
            InteractionImpossible = true;
        }

        if (CheckClicked() && (interactionCount > 0 || wasClicked) && !Clicked && InteractionPossible)
        {
            if (!wasClicked)
            {            
                interactionCount--;
            }
            
            AudioManager.PlaySound("Audio/s01");
            //Console.WriteLine("1");

            //Console.WriteLine(interactionCount);

            foreach (Objects obj in objectList)
            {
                if (obj == this)
                {
                    Clicked = true;
                    wasClicked = true;
                }
                else
                    obj.Clicked = false;
            }
        }
        else
        if (CheckClicked() && InteractionImpossible)
        {
            AudioManager.PlaySound("Audio/s03");
            //Console.WriteLine("3");
        }
    }*/

    private bool CheckClicked(MoveSelect moving)
    {
        if (Clicked)
            return false;

        if ((InputManager.MouseState.LeftButton == ButtonState.Pressed || InputManager.IsActionTriggered(InputManager.Action.Ok)) && InteractionPossible)
        {
            for (int i = mensagens.Count - 1; i >= 0; i--)
            {
                if (GameSession.CheckAllConditions(mensagens[i].Need))
                {
                    pista = mensagens[i].Pista;
                    mensagens[i].GiveCondition();
                    break;
                }
            }
            return true;
        }
        return false;
    }

    internal void AddMessage(Mensagem msg)
    {
        mensagens.Add(msg);
    }

    internal Objects Copy()
    {
        Objects o = new Objects(posicao, imagem, font);
        o.InteractionPossible = InteractionPossible;
        o.InteractionImpossible = InteractionImpossible;
        o.Clicked = Clicked;
        o.wasClicked = wasClicked;
        o.mensagens = mensagens;
        o.pista = pista;
        o.need = need;
        o.give = give;

        return o;

    }

    internal void Deselect()
    {
        Clicked = false;
    }

    internal bool IsSameObject(Objects toRemove)
    {
        if(toRemove.Messages.Count != mensagens.Count)
            return false;

        for (int i = 0; i < toRemove.mensagens.Count; i++ )
        {
            if (!toRemove.mensagens[i].Pista.Equals(mensagens[i].Pista))
                return false;
        }

        return true;
    }

    internal void Update(List<Objects> objectList, ref int interactionCount, MoveSelect moving, ref int objSelected, int i)
    {
        if (Globals.FirstItem)
            return;

        if (moving == MoveSelect.MOUSE)
            CheckSelected();
        else
        {
            if (objSelected == i)
                InteractionPossible = true;
            else
                InteractionPossible = false;
        }

        InteractionImpossible = false;

        if (InteractionPossible && !(interactionCount > 0 || wasClicked))
        {
            InteractionPossible = false;
            InteractionImpossible = true;
        }

        if (CheckClicked(moving) && (interactionCount > 0 || wasClicked) && !Clicked && InteractionPossible)
        {
            if (!wasClicked)
            {
                interactionCount--;
            }

            AudioManager.PlaySound("Audio/s01");
            //Console.WriteLine("1");

            //Console.WriteLine(interactionCount);

            foreach (Objects obj in objectList)
            {
                if (obj == this)
                {
                    Clicked = true;
                    wasClicked = true;
                }
                else
                    obj.Clicked = false;
            }
        }
        else
            if (CheckClicked(moving) && InteractionImpossible)
            {
                AudioManager.PlaySound("Audio/s03");
                //Console.WriteLine("3");
            }
    }
}
